{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "311116e8",
   "metadata": {},
   "outputs": [],
   "source": [
    "deployment = \"gpt4\"\n",
    "model = \"gpt-4\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9963a591",
   "metadata": {},
   "source": [
    "# 回顾"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "d86dadbe",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain import PromptTemplate, OpenAI, LLMChain\n",
    "from langchain.chat_models import AzureChatOpenAI\n",
    "from langchain.utilities import GoogleSerperAPIWrapper\n",
    "from langchain.chat_models import AzureChatOpenAI\n",
    "# from langchain.chat_models import ChatOpenAI #直接访问OpenAI的GPT服务\n",
    "\n",
    "#llm = ChatOpenAI(model_name=\"gpt-4\", temperature=0) #直接访问OpenAI的GPT服务\n",
    "llm = AzureChatOpenAI(deployment_name = deployment, model_name=model, temperature=0, max_tokens=200) #通过Azure的OpenAI服务\n",
    "\n",
    "# import os\n",
    "# os.environ[\"SERPER_API_KEY\"] = \"\"\n",
    "# https://serper.dev\n",
    "\n",
    "def query_web(question):\n",
    "    search = GoogleSerperAPIWrapper()\n",
    "    return search.run(question)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "163f3aeb",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Saturday, September 9, 2023\n"
     ]
    }
   ],
   "source": [
    "\n",
    "print(query_web(\"what date is today?\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "91246f60",
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_current_cluster_state(cluster_name):\n",
    "    return  \"\"\"ERROR: Failed to pull image \"chaocai/docker/dsp:latest\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "42901684",
   "metadata": {},
   "outputs": [],
   "source": [
    "funcs = {\n",
    "    \"get_current_cluster_state\": get_current_cluster_state,\n",
    "    \"query_web\":query_web,\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "191e2635",
   "metadata": {},
   "outputs": [],
   "source": [
    "import openai\n",
    "import json\n",
    "def run(input):\n",
    "    msg=[{\"role\":\"user\",\"content\":input}]\n",
    "    ret = run_conversation(msg)\n",
    "    return ret[\"content\"] \n",
    "\n",
    "def run_conversation(msg):\n",
    "    response = openai.ChatCompletion.create(\n",
    "        engine=deployment,\n",
    "        model=model,\n",
    "        messages=msg,\n",
    "        functions=[\n",
    "     \n",
    "            {\n",
    "                \"name\": \"get_current_cluster_state\",\n",
    "                \"description\": \"Get the current state in a given cluster\",\n",
    "                \"parameters\": {\n",
    "                    \"type\": \"object\",\n",
    "                    \"properties\": {\n",
    "                        \"cluster_name\": {\n",
    "                            \"type\": \"string\",\n",
    "                            \"description\": \"the name of the cluster\",\n",
    "                        },\n",
    "                        \n",
    "                    },\n",
    "                    \"required\": [\"cluster_name\"],\n",
    "                },\n",
    "            },\n",
    "     \n",
    "            {\n",
    "                \"name\": \"query_web\",\n",
    "                \"description\": \"Get a realtime info/unknown info from web\",\n",
    "                \"parameters\": {\n",
    "                    \"type\": \"object\",\n",
    "                    \"properties\": {\n",
    "                        \"question\": {\n",
    "                            \"type\": \"string\",\n",
    "                            \"description\": \"the query/question\",\n",
    "                        },\n",
    "                        \n",
    "                    },\n",
    "                    \"required\": [\"query\"],\n",
    "                },\n",
    "            }\n",
    "        ],\n",
    "        function_call=\"auto\",\n",
    "    )\n",
    "\n",
    "    message =  response[\"choices\"][0][\"message\"]\n",
    "    \n",
    "    # 如果不需要调用function，则直接返回结果\n",
    "    if not message.get(\"function_call\"):\n",
    "        return message\n",
    "    \n",
    "    # 从\n",
    "    function_name = message[\"function_call\"][\"name\"]\n",
    "    function_args = json.loads(message[\"function_call\"][\"arguments\"])\n",
    "    print(function_args)\n",
    "    res = funcs[function_name](function_args[\"question\"])\n",
    "    message[\"content\"]=None\n",
    "    msg.append(message)\n",
    "    msg.append({\n",
    "                \"role\": \"function\",\n",
    "                \"name\": function_name,\n",
    "                \"content\": res,\n",
    "            })\n",
    "    return run_conversation(msg)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "0aed4c3e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'question': '北京今天的天气如何'}\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'今天北京的天气大约是69°F（约20.5°C），建议您可以穿着轻薄的长袖或者短袖，如果觉得有些凉，可以加一件薄外套。'"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "run(\"北京今天适合穿什么\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a1897831",
   "metadata": {},
   "source": [
    "# LangChain Agent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "93e34e3a",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.agents import initialize_agent, Tool\n",
    "from langchain.chat_models import AzureChatOpenAI\n",
    "from langchain.chains import LLMRequestsChain\n",
    "from langchain.chains import LLMChain\n",
    "from langchain.prompts import PromptTemplate\n",
    "import time\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "333be573",
   "metadata": {},
   "outputs": [],
   "source": [
    "# from langchain.chat_models import ChatOpenAI #直接访问OpenAI的GPT服务\n",
    "\n",
    "#llm = ChatOpenAI(model_name=\"gpt-4\", temperature=0) #直接访问OpenAI的GPT服务\n",
    "llm = AzureChatOpenAI(deployment_name = deployment, model_name=model, temperature=0, max_tokens=200) #通过Azure的OpenAI服务\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "d991bdb7",
   "metadata": {},
   "outputs": [],
   "source": [
    "tools = [\n",
    "    Tool(\n",
    "        name = \"Get current info\",func=query_web,\n",
    "        description=\"\"\"invoke it for when you need to answer questions about current info.\n",
    "             And the input should be a search query.\"\"\"),\n",
    "    Tool(\n",
    "        name=\"Get current cluster state\", func=get_current_cluster_state,\n",
    "        description=\"\"\"invoke it for when you need to get the current state in a given cluster, \n",
    "        And the input should be service name.\"\"\")\n",
    "]\n",
    "\n",
    "agent = initialize_agent(tools, llm, agent=\"zero-shot-react-description\", max_iterations=3, verbose=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "bb69074e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3m我需要获取当前的天气信息来回答这个问题。\n",
      "Action: Get current info\n",
      "Action Input: 北京今天的天气\u001b[0m\n",
      "Observation: \u001b[36;1m\u001b[1;3m72°F\u001b[0m\n",
      "Thought:\u001b[32;1m\u001b[1;3m根据观察到的天气信息，我可以推断出适合穿什么。\n",
      "Final Answer: 今天北京的天气是72°F，所以穿一件长袖T恤和一条牛仔裤应该很合适。\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'今天北京的天气是72°F，所以穿一件长袖T恤和一条牛仔裤应该很合适。'"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "agent.run(\"北京今天穿什么合适？\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "fef8cef5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3m首先，我需要知道ADX集群的当前状态。\n",
      "Action: Get current cluster state\n",
      "Action Input: ADX\u001b[0m\n",
      "Observation: \u001b[33;1m\u001b[1;3mERROR: Failed to pull image \"chaocai/docker/dsp:latest\u001b[0m\n",
      "Thought:\u001b[32;1m\u001b[1;3m看来ADX集群的问题在于无法拉取最新的镜像。我需要查找如何解决这个问题。\n",
      "Action: Get current info\n",
      "Action Input: 如何修复无法拉取docker镜像的问题\u001b[0m\n",
      "Observation: \u001b[36;1m\u001b[1;3m原因： 系统的时间和docker hub时间不一致,需要做系统时间与网络时间同步 · 安装时间同步 sudo yum -y install ntp ntpdate. 1 · 同步时间 sudo ntpdate cn. 更新：重启后/etc/resolv.conf的修改确实失效恢复到默认。解决办法：. 在/etc/sysconfig/network-scripts/ifcfg-eth<N> 文件中加入PEERDNS 选项。<N>可以 ... 您好，这个镜像确实是存在，我用您的命令到ssh中拉取镜像是可以拉取的，您拉取不成功，可能是因为您的网络环境和Docker Hub之间的连接不稳定或者速度较慢，或者他们在拉取时的时间Docker Hub的镜像仓库处于不可用状态，导致拉取镜像失败。 1、检查您的网络连接是否正常，并尝试使用 ... 在节点性能较差或镜像较大时，可能出现镜像无法成功下载，负载启动失败的现象。 解决方案：. (推荐)方法一：登录节点使用docker pull命令手动下拉镜像， ... 网络问题：Docker 拉取镜像需要访问Docker Hub 或其他镜像仓库，如果网络不稳定或连接不畅，可能会导致卡住。可以尝试检查网络连接，并尝试使用VPN 或更改网络环境等 ... 反馈bug/问题模板，提建议请删除1.关于你要提交的问题Q：是否搜索了issue (使用\"x\" 选择) [x ] 没有类似的issue 2. 详细叙述(1) 具体问题A： ... 我正在使用最简单的docker文件从另一个镜像创建docker镜像： FROM 成功构建和标记映像。但是，当我将其推送到Azure容器注册表并拉取镜像时， ... 如果我们无法拉取一个特定的镜像，可能是因为该镜像不存在于Docker镜像仓库中 ... 我们还可以尝试重新配置Docker Credential Helper来修复权限问题。 然而，在某些情况下，我们可能会遇到服务器内网无法拉取Docker 镜像的问题。本文将介绍可能导致该问题的原因，并提供相应的解决方案。 授权问题：请确认您是否已经登录Docker Hub 或Alibaba Cloud Registry，并且具备拉取镜像的权限。如果需要进行身份验证，请使用 docker login 命令进行 ...\u001b[0m\n",
      "Thought:\u001b[32;1m\u001b[1;3m根据我找到的信息，无法拉取docker镜像的问题可能是由于网络问题、服务器时间不一致、镜像不存在或者权限问题等原因导致的。解决这个问题的方法可能包括检查网络连接、同步服务器时间、手动拉取镜像、重新配置Docker Credential Helper或者使用docker login命令进行身份验证等。\n",
      "Final Answer: 修复ADX集群的方法可能包括：1. 检查网络连接，确保网络稳定；2. 同步服务器时间，确保与docker hub时间一致；3. 手动使用docker pull命令拉取镜像；4. 重新配置Docker Credential Helper来修复权限问题；5. 使用docker login命令进行身份验证，确保具备拉\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'修复ADX集群的方法可能包括：1. 检查网络连接，确保网络稳定；2. 同步服务器时间，确保与docker hub时间一致；3. 手动使用docker pull命令拉取镜像；4. 重新配置Docker Credential Helper来修复权限问题；5. 使用docker login命令进行身份验证，确保具备拉'"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "agent.run(\"如何修复的ADX集群？\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9d25b3b9",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "840119a0",
   "metadata": {},
   "source": [
    "# 利用LangChain中的工具"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "8919d594",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Requirement already satisfied: wolframalpha in /Users/mbj0593/anaconda3/lib/python3.11/site-packages (5.0.0)\n",
      "Requirement already satisfied: xmltodict in /Users/mbj0593/anaconda3/lib/python3.11/site-packages (from wolframalpha) (0.13.0)\n",
      "Requirement already satisfied: more-itertools in /Users/mbj0593/anaconda3/lib/python3.11/site-packages (from wolframalpha) (8.12.0)\n",
      "Requirement already satisfied: jaraco.context in /Users/mbj0593/anaconda3/lib/python3.11/site-packages (from wolframalpha) (4.3.0)\n",
      "Note: you may need to restart the kernel to use updated packages.\n"
     ]
    }
   ],
   "source": [
    "pip install wolframalpha"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "3fad7a4e",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.utilities.wolfram_alpha import WolframAlphaAPIWrapper\n",
    "def wolfram_api(question):\n",
    "    wolfram = WolframAlphaAPIWrapper()\n",
    "    return wolfram.run(question)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "c63ba80c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Assumption: 2 x + 5 = -3 x + 7 \\nAnswer: x = 2/5'"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "wolfram_api(\"What is 2x+5 = -3x + 7?\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "20ff129d",
   "metadata": {},
   "outputs": [],
   "source": [
    "tools = [\n",
    "    Tool(\n",
    "        name = \"Get current info\",func=query_web,\n",
    "        description=\"\"\"invoke it for when you need to answer questions about current info.\n",
    "             And the input should be a search query.\"\"\"),\n",
    "    Tool(\n",
    "        name=\"Get current cluster state\", func=get_current_cluster_state,\n",
    "        description=\"\"\"invoke it for when you need to get the current state in a given cluster, \n",
    "        And the input should be service name.\"\"\"),\n",
    "    Tool(\n",
    "        name=\"Invoke WolframAlpha API\", func=wolfram_api,\n",
    "        description=\"\"\"invoke it for when you need to anwser or solve a mathematical question, \n",
    "        And the input is the mathematical equations\"\"\")\n",
    "]\n",
    "\n",
    "agent = initialize_agent(tools, llm, agent=\"zero-shot-react-description\", max_iterations=10, verbose=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "3cff4a67",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3m这是一个数学问题，我需要解决一个包含两个未知数的方程组。鸡的数量我将用x表示，免子的数量我将用y表示。根据问题，我可以得到以下两个方程：x + y = 20 (头的数量) 和 3x + 4y = 71 (脚的数量)。\n",
      "Action: Invoke WolframAlpha API\n",
      "Action Input: solve the equations x + y = 20 and 3x + 4y = 71\u001b[0m\n",
      "Observation: \u001b[38;5;200m\u001b[1;3mAssumption: solve x + y = 20\n",
      "3 x + 4 y = 71 \n",
      "Answer: x = 9 and y = 11\u001b[0m\n",
      "Thought:\u001b[32;1m\u001b[1;3m我现在知道最后的答案\n",
      "Final Answer: 笼子里有9只鸡和11只免子。\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'笼子里有9只鸡和11只免子。'"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "agent.run(\"在一个外星球上，这里的鸡都长着3只脚1个头，免子有4只脚1个头，一个装着鸡和免子的笼子里一共有20个头，71只脚，请问笼子里各有多少只鸡和免子？\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b794debe",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
